package org.xxpay.pay.channel.jfpay;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.xxpay.core.common.constant.PayConstant;
import org.xxpay.core.common.domain.api.AbstractRes;
import org.xxpay.core.common.domain.api.ApiBuilder;
import org.xxpay.core.common.domain.api.PayRes;
import org.xxpay.core.common.domain.api.msg.QueryRetMsg;
import org.xxpay.core.common.util.*;
import org.xxpay.core.common.vo.DBApplicationConfig;
import org.xxpay.core.entity.PayOrder;
import org.xxpay.pay.channel.BasePayment;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class JfpayPaymentService extends BasePayment {

    private static final MyLog _log = MyLog.getLog(JfpayPaymentService.class);

    @Override
    public String getChannelName() {
        return JfpayConfig.CHANNEL_NAME;
    }

    @Override
    public AbstractRes pay(PayOrder payOrder) {
        String channelId = payOrder.getChannelId();
        switch (channelId) {
            case JfpayConfig.CHANNEL_NAME_ALIPAY_H5 :
                return doPay(payOrder, "904");
            case JfpayConfig.CHANNEL_NAME_WXPAY_H5 :
                return doPay(payOrder, "901");
        }
        return ApiBuilder.bizError("不支持的渠道[channelId="+channelId+"]");
    }

    /** 支付请求 **/
    private AbstractRes doPay(PayOrder payOrder, String payType) {

        String logPrefix = "["+ JfpayConfig.CHANNEL_NAME + "下单]";
        String payOrderId = payOrder.getPayOrderId();
        try {

            JfpayConfig jfpayConfig = new JfpayConfig(getPayParam(payOrder));

            DBApplicationConfig dbConfig = getDBApplicationConfig();

            PayRes retObj = ApiBuilder.buildSuccess(PayRes.class);
            // 订单参数
            Map<String, String> paramsMap = new HashMap<>();
            paramsMap.put("pay_memberid", jfpayConfig.getMemberId());   //商户号
            paramsMap.put("pay_orderid", payOrderId);   //订单号
            paramsMap.put("pay_applydate", DateUtil.date2Str(new Date()));  //提交时间 时间格式：2016-12-26 18:18:18
            paramsMap.put("pay_bankcode", payType);   //银行编码
            paramsMap.put("pay_notifyurl", super.getNotifyUrl(getChannelName(), dbConfig));   //服务端通知
            paramsMap.put("pay_callbackurl", super.getReturnUrl(getChannelName(), dbConfig)); //页面跳转通知
            paramsMap.put("pay_amount", AmountUtil.convertCent2Dollar(payOrder.getAmount()+""));    //订单金额
            // 订单签名
            paramsMap.put("pay_md5sign", JfpayUtil.getSign(paramsMap.get("pay_amount"), paramsMap.get("pay_applydate"), paramsMap.get("pay_bankcode"), paramsMap.get("pay_callbackurl"), paramsMap.get("pay_memberid"), paramsMap.get("pay_notifyurl"), paramsMap.get("pay_orderid"), jfpayConfig.getApiKey()));    //签名
            paramsMap.put("pay_productname", payOrder.getSubject()); //商品名称 必填 & 不参与签名

            //发起下单请求
            String reqData = XXPayUtil.genUrlParams2(paramsMap);
            String reqUrl = jfpayConfig.getReqUrlHost() + "?" + reqData; //请求网关地址
            _log.info("{}请求地址:{}", logPrefix, reqUrl);
            String result = XXPayUtil.call4Post(reqUrl);
            _log.info("{}返回数据:{}", logPrefix, result);
            if(StringUtils.isBlank(result)) {
                return ApiBuilder.bizError("上游通道返回空!");
            }

            JSONObject resObj = JSONObject.parseObject(result);

            String code = resObj.getString("code");
            String msg = resObj.getString("msg");
            if(!"200".equals(code)) {
                return ApiBuilder.bizError("调用通道下单失败!返回:" + msg);
            }


            // 请求地址
            JSONObject dataObj = resObj.getJSONObject("data");
            String toPayUrl = dataObj.getString("payUrl");
            String channelOrderId = dataObj.getString("sn");

            retObj.setPayJumpUrl(toPayUrl);      // 可以通过该地址跳转到支付中心界面完成支付(URL)
            StringBuffer payForm = new StringBuffer();
            payForm.append("<script>window.location.href = '"+toPayUrl+"';</script>");

            retObj.setPayUrl(payForm.toString());
            retObj.setPayMethod(PayConstant.PAY_METHOD_FORM_JUMP);

            int updateCount = commonService.payOrderService.updateStatus4Ing(payOrder.getPayOrderId(), channelOrderId);
            _log.info("[{}]更新订单状态为支付中:payOrderId={},result={}", getChannelName(), payOrder.getPayOrderId(), updateCount);

            return retObj;

        } catch (Exception e) {
            _log.error("{}异常， orderId={}", logPrefix, payOrderId, e);
            return ApiBuilder.bizError("调起接口失败!["+e.getMessage()+"]");
        }
    }

    @Override
    public QueryRetMsg query(PayOrder payOrder) {
        String logPrefix = "["+ JfpayConfig.CHANNEL_NAME + "查单]";
        String payOrderId = payOrder.getPayOrderId();
        _log.info("{}开始查询订单,payOrderId={}", logPrefix, payOrderId);
        return QueryRetMsg.waiting();  //支付中
    }

}
